package org.springblogs.batch.quartz.stock;

import java.util.Calendar;
import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springblogs.batch.config.stock.AbstractRepositoryBatchJob;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.beans.factory.annotation.Autowired;

public abstract class AbstractScheduledTask<J extends AbstractRepositoryBatchJob<?, ?>> {
	protected final Log log = LogFactory.getLog(this.getClass());
	@Autowired
	private JobLauncher jobLauncher;
	@Autowired
	private JobRepository jobRepository;

	public void execute() {
		int retry =0;
		while(retry < 3) {
			try {
				jobLauncher.run(getJob().getJob(), getJobParameters());
				break;
			} catch (Exception e) {
				retry++;
				System.out.println(getJob().getJob().getName());
				JobExecution jobExecution = jobRepository.getLastJobExecution(getJob().getJob().getName(), getJobParameters());
				Collection<StepExecution> executions = jobExecution.getStepExecutions();
				System.out.println(executions.size());
				jobExecution.setStatus(BatchStatus.FAILED);
				jobExecution.setEndTime(Calendar.getInstance().getTime());
				if (jobExecution.getExitStatus().equals(ExitStatus.UNKNOWN)) {
					jobExecution.setExitStatus(ExitStatus.FAILED.addExitDescription(e));
				}
				for(StepExecution se:executions) {
					se.setStatus(BatchStatus.FAILED);
					jobRepository.update(se);
				}
				jobRepository.update(jobExecution);
				
				e.printStackTrace();
			}
		}
	}

	public abstract J getJob();
	
	public JobParameters getJobParameters() {
		return new JobParameters();
	}

	public abstract void taskScheduled();

}
